package com.wanwu.channel.core.util;

import com.alibaba.fastjson.JSONObject;
import com.wanwu.channel.common.util.Md5Encrypt;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * @ClassName WechatSignUtil
 * @Description 微信支付签名工具
 * @Author husheng
 * @Date 2020-01-03 10:55
 */
public class WechatSignUtil {

    private static final Logger logger = LoggerFactory.getLogger(WechatSignUtil.class);

    /**
     * 签名
     *
     * @param reqObj 入参不带sign
     * @param key    微信平台商户key
     * @return
     */
    public static void sign(JSONObject reqObj, String key) {
        SortedMap<String, String> sortedMap = new TreeMap<>();
        for (String mkey : reqObj.keySet()) {
            String value = "";
            Object obj = reqObj.get(mkey);
            if (obj instanceof Integer) {
                value = obj.toString();
            } else {
                value = (String) obj;
            }
            sortedMap.put(mkey, value);
        }
        String sign = createSignBySortedMap(sortedMap, key);
        reqObj.put("sign", sign);
    }

    /**
     * 验证签名
     *
     * @param xml
     * @param key
     */
    public static boolean verifySign(String xml, String key) {
        Map<String, String> respXmlMap = WXPayUtil.xmlToMap(xml);
        String sign = respXmlMap.get("sign");
        if (StringUtils.isEmpty(sign)) {
            return false;
        }
        //sign不参与签名
        respXmlMap.remove("sign");
        SortedMap<String, String> sortedMap = new TreeMap<>();
        for (String rkey : respXmlMap.keySet()) {
            sortedMap.put(rkey, respXmlMap.get(rkey));
        }
        String localSign = createSignBySortedMap(sortedMap, key);
        return sign.equals(localSign);
    }

    private static String createSignBySortedMap(SortedMap<String, String> parameters, String key) {
        StringBuffer sb = new StringBuffer();
        StringBuffer sbkey = new StringBuffer();
        //所有参与传参的参数按照accsii排序（升序）
        Set es = parameters.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            Object v = entry.getValue();
            //空值不传递，不参与签名组串
            if (null != v && !"".equals(v)) {
                sb.append(k + "=" + v + "&");
                sbkey.append(k + "=" + v + "&");
            }
        }
        //System.out.println("字符串:"+sb.toString());
        sbkey = sbkey.append("key=" + key);
        //LogUtil.info(logger, "排序后待签名字符串：{0}", sbkey.toString());
        //MD5加密,结果转换为大写字符
        String sign = Md5Encrypt.md5Sign(sbkey.toString());
        //LogUtil.info(logger, "生成MD5签名串：{0}", sign);
        return sign;
    }


    public static void main(String[] args) {
        String key = "123456";
        Map<String, Object> reqMap = new HashMap<>();
        reqMap.put("appid", 1);
        reqMap.put("mch_id", "2");
        reqMap.put("device_info", "3");
        reqMap.put("body", "4");
        reqMap.put("nonce_str", "5");
    }
}
